package com.zang.blogz.strategy.impl;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.StrUtil;
import com.zang.blogz.constant.PublicConstant;
import com.zang.blogz.entity.Article;
import com.zang.blogz.entity.Category;
import com.zang.blogz.entity.Tag;
import com.zang.blogz.exception.BizException;
import com.zang.blogz.model.input.ro.ArticleReviseRO;
import com.zang.blogz.model.output.ImportArticleRO;
import com.zang.blogz.service.ArticleService;
import com.zang.blogz.service.ArticleTagService;
import com.zang.blogz.strategy.ArticleImportStrategy;
import io.github.vampireachao.stream.core.optional.Opp;
import io.github.vampireachao.stream.core.stream.Steam;
import io.github.vampireachao.stream.plugin.mybatisplus.Database;
import io.github.vampireachao.stream.plugin.mybatisplus.Many;
import io.github.vampireachao.stream.plugin.mybatisplus.One;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

import static com.zang.blogz.enmus.ArticleStatusEnum.DRAFT;
import static com.zang.blogz.enmus.ArticleStatusEnum.PUBLIC;

/**
 * @author ZVerify
 * @since 2022/10/13 19:15
 **/
@Slf4j
@Service("normalArticleImportStrategyImpl")
public class NormalArticleImportStrategyImpl implements ArticleImportStrategy {

    @Autowired
    private ArticleService articleService;


    @Override
    public ArticleReviseRO importArticles(MultipartFile file, ImportArticleRO importArticleRO) {

        // 获取文件名作为文章标题
        String articleTitle = Opp.ofStr(file.getOriginalFilename()).orElseThrow(() -> new NullPointerException("文件名不能为NULL"));

        // 获取文章内容
        StringBuilder articleContent = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {
            while (reader.ready()) {
                articleContent.append((char) reader.read());
            }
        } catch (IOException e) {
            log.error(StrUtil.format("导入文章失败, 堆栈:{}", ExceptionUtil.stacktraceToString(e)));
            throw new BizException("导入文章失败");
        }

        List<String> oldData = Many.of(Tag::getTagName).in(importArticleRO.getTagsNames()).value(Tag::getTagName).query();
        List<Tag> tags = Steam.of(importArticleRO.getTagsNames()).filter(tagName -> !oldData.contains(tagName)).map(tagName -> Tag.builder().tagName(tagName).build()).toList();

        Database.saveBatch(tags);

        // 保存文章
        ArticleReviseRO articleReviseRO = ArticleReviseRO.builder()
                .articleTitle(articleTitle)
                .articleCover(importArticleRO.getArticleCover())
                .type(PUBLIC.getStatus())
                .tagList(Steam.of(Many.of(Tag::getTagName).in(importArticleRO.getTagsNames()).value(Tag::getId).query()).toList())
                .categoryName(importArticleRO.getCategoryName())
                .articleContent(articleContent.toString())
                .status(PUBLIC.getStatus())
                .isDelete(PublicConstant.ZERO)
                .build();

        articleService.reviseOrSaveArticle(articleReviseRO);
        return articleReviseRO;
    }
}
